#include "Drivers/CMSIS/Device/ST/STM32F4xx/Include/stm32f4xx.h" // Device header
#include "stm32f4xx_conf.h"
#include "Motor.h"

void Motor_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
    // 使能时钟
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
	
	
// ****************************************************配置IN引脚******************************************************************//
  GPIO_InitStructure.GPIO_Pin = Motor1_IN1_PIN|Motor1_IN2_PIN|Motor2_IN1_PIN|Motor2_IN2_PIN|Motor3_IN1_PIN;       // 配置在GPIOE的IN引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;    // 输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   // 推挽输出
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;   // 下拉电阻
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 低速模式
  GPIO_Init(GPIOE, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = Motor4_IN2_PIN;       // 配置在GPIOB的IN引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;    // 输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   // 推挽输出
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;   // 下拉电阻
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 低速模式
  GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_InitStructure.GPIO_Pin = Motor3_IN2_PIN|Motor4_IN1_PIN;       // 配置在GPIOD的IN引脚
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;    // 输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;   // 推挽输出
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;   // 下拉电阻
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 低速模式
  GPIO_Init(GPIOD, &GPIO_InitStructure);
    
  // 初始状态均为高电平
  GPIO_ResetBits(GPIOE, Motor1_IN1_PIN|Motor1_IN2_PIN|Motor2_IN1_PIN|Motor2_IN2_PIN|Motor3_IN1_PIN);
	GPIO_ResetBits(GPIOB, Motor4_IN2_PIN);
	GPIO_ResetBits(GPIOD, Motor3_IN2_PIN|Motor4_IN1_PIN);
// **************************************************************************************************************************************//
	
// ****************************************************配置PWM引脚******************************************************************//
		TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
    TIM_OCInitTypeDef TIM_OCInitStruct;
    
    // 配置GPIO
    GPIO_InitStructure.GPIO_Pin = Motor1_PWM_PIN | Motor2_PWM_PIN | Motor3_PWM_PIN | Motor4_PWM_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
	
    // 引脚复用映射
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1);  // PE9->TIM1_CH1
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1);  // PE11->TIM1_CH2
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource13, GPIO_AF_TIM1);  // PE13->TIM1_CH3
    GPIO_PinAFConfig(GPIOE, GPIO_PinSource14, GPIO_AF_TIM1);  // PE14->TIM1_CH4

    //配置定时器时基
    TIM_TimeBaseStruct.TIM_Prescaler = 168-1;    
    TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseStruct.TIM_Period = 100 - 1; //
    TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(Motor_TIM, &TIM_TimeBaseStruct);
    //配置PWM模式
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM2;
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;
		TIM_OCInitStruct.TIM_Pulse=0;//初始时为0
    
    TIM_OC1Init(Motor_TIM, &TIM_OCInitStruct);
    TIM_OC1PreloadConfig(Motor_TIM, TIM_OCPreload_Enable);
    
    TIM_OC2Init(Motor_TIM, &TIM_OCInitStruct);
    TIM_OC2PreloadConfig(Motor_TIM, TIM_OCPreload_Enable);
    
    TIM_OC3Init(Motor_TIM, &TIM_OCInitStruct);
    TIM_OC3PreloadConfig(Motor_TIM, TIM_OCPreload_Enable);
		
		TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OC4Init(Motor_TIM, &TIM_OCInitStruct);
    TIM_OC4PreloadConfig(Motor_TIM, TIM_OCPreload_Enable);

    
    //启动定时器
    TIM_Cmd(Motor_TIM, ENABLE);
    TIM_ARRPreloadConfig(Motor_TIM, ENABLE);  // 使能ARR预装载
		
		TIM_CtrlPWMOutputs(TIM1, ENABLE);
// **************************************************************************************************************************************//
	
// ****************************************************配置RARB引脚******************************************************************//




// **************************************************************************************************************************************//

	//初始化电机状态
	motor_1.derection=0;
	motor_1.speed=0;
	motor_2.derection=0;
	motor_2.speed=0;
	motor_3.derection=0;
	motor_3.speed=0;
	motor_4.derection=0;
	motor_4.speed=0;
}

struct Motor_State Get_Motor_state(uint8_t ID){
	struct Motor_State motor_state;
	switch (ID){
		case Motor1:
			motor_state=motor_1;
		break;
		
		case Motor2:
			motor_state=motor_2;
		break;
		
		case Motor3:
			motor_state=motor_3;
		break;
		
		case Motor4:
			motor_state=motor_4;
		break;
	}
	return motor_state;
}

void PWM_SetCompare1(uint16_t compare)
{
	TIM_SetCompare1(Motor_TIM,compare);
}
void PWM_SetCompare2(uint16_t compare)
{
	TIM_SetCompare2(Motor_TIM,compare);
}
void PWM_SetCompare3(uint16_t compare)
{
	TIM_SetCompare3(Motor_TIM,compare);
}
void PWM_SetCompare4(uint16_t compare)
{
	TIM_SetCompare4(Motor_TIM,compare);
}

void Motor_SetSpeed(uint8_t ID,int16_t Speed)
{
	switch (ID){
		case Motor1:
			if(Speed >= 0)
			{
				GPIO_SetBits(Motor1_IN1_GPIO,Motor1_IN1_PIN);
				GPIO_ResetBits(Motor1_IN2_GPIO,Motor1_IN2_PIN);
				PWM_SetCompare1(Speed);
				if(Speed == 0)
					motor_1.derection=STOP;
				else
					motor_1.derection=FORWARD;
			}
			else 
			{
				GPIO_ResetBits(Motor1_IN1_GPIO,Motor1_IN1_PIN);
				GPIO_SetBits(Motor1_IN2_GPIO,Motor1_IN2_PIN);
				PWM_SetCompare1(-Speed);
				motor_1.derection=REVERSE;
			}
			motor_1.speed=Speed;
		break;
		
		case Motor2:
			if(Speed >= 0)
			{
				GPIO_SetBits(Motor2_IN1_GPIO,Motor2_IN1_PIN);
				GPIO_ResetBits(Motor2_IN2_GPIO,Motor2_IN2_PIN);
				PWM_SetCompare2(Speed);
				if(Speed == 0)
					motor_2.derection=STOP;
				else
					motor_2.derection=FORWARD;
			}
			else
			{
				GPIO_ResetBits(Motor2_IN1_GPIO,Motor2_IN1_PIN);
				GPIO_SetBits(Motor2_IN2_GPIO,Motor2_IN2_PIN);
				PWM_SetCompare2(-Speed);
				motor_2.derection=REVERSE;
			}
			motor_2.speed=Speed;
		break;
		
		case Motor3:
			if(Speed >= 0)
			{
				GPIO_SetBits(Motor3_IN1_GPIO,Motor3_IN1_PIN);
				GPIO_ResetBits(Motor3_IN2_GPIO,Motor3_IN2_PIN);
				PWM_SetCompare3(Speed);
				if(Speed == 0)
					motor_3.derection=STOP;
				else
					motor_3.derection=FORWARD;
			}
			else
			{
				GPIO_ResetBits(Motor3_IN1_GPIO,Motor3_IN1_PIN);
				GPIO_SetBits(Motor3_IN2_GPIO,Motor3_IN2_PIN);
				PWM_SetCompare3(-Speed);
				motor_3.derection=REVERSE;
			}
			motor_3.speed=Speed;
		break;
		
		case Motor4:
			if(Speed >= 0)
			{
				GPIO_SetBits(Motor4_IN1_GPIO,Motor4_IN1_PIN);
				GPIO_ResetBits(Motor4_IN2_GPIO,Motor4_IN2_PIN);
				PWM_SetCompare4(Speed);
				if(Speed == 0)
					motor_4.derection=STOP;
				else
					motor_4.derection=FORWARD;
			}
			else 
			{
				GPIO_ResetBits(Motor4_IN1_GPIO,Motor4_IN1_PIN);
				GPIO_SetBits(Motor4_IN2_GPIO,Motor4_IN2_PIN);
				PWM_SetCompare4(-Speed);
				motor_4.derection=REVERSE;
			}
			motor_4.speed=Speed;
		break;
	}

}
